package com.easy.security;

import com.easy.util.JwtUtils;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.List;

//这是一个基于 Spring Security 的 JWT 鉴权过滤器。它会在每个请求进入你的应用之前运行：
// 校验是否需要鉴权、从请求头取出 JWT、验证并解析、
// 把用户身份和角色放进 SecurityContext，让后续的控制器/权限注解能识别“谁在访问、拥有什么权限”。
@Component
//保证每次请求只执行一次过滤逻辑
public class JwtAuthFilter extends OncePerRequestFilter {

    @Autowired
    private JwtUtils jwtUtils;

    // 白名单（登录/静态资源等）
    private static final String[] EXCLUDES = {
            "/api/auth", "/api/auth/", "/api/auth/login",
            "/public/", "/assets/", "/error"
    };

    //主要用于JWT过滤器中跳过对白名单路径的认证检查。
    private boolean excluded(String uri) {
        if (uri == null) return true;
        String p = uri.replaceAll("/+", "/");
        for (String e : EXCLUDES) {
            if (p.equals(e) || p.startsWith(e)) return true;
        }
        return false;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain)
            throws ServletException, IOException {

        // 预检/白名单放行
        if ("OPTIONS".equalsIgnoreCase(req.getMethod()) || excluded(req.getRequestURI())) {
            chain.doFilter(req, res);
            return;
        }

        //从头里取 token
        //从 HTTP 请求头 里获取名为 "Authorization" 的字段。
        String header = req.getHeader("Authorization");
        //判断请求头不为空，且内容以 "Bearer " 开头
        if (header != null && header.startsWith("Bearer ")) {
            //substring(7) 是把前 7 个字符 "Bearer " 去掉
            String token = header.substring(7);
            if (jwtUtils.validateToken(token)) {
                // 获取用户ID
                Integer uid = jwtUtils.getUserIdFromToken(token);
                // 获取角色
                String role = jwtUtils.getRoleFromToken(token);  // 从token中提取角色信息
                // 判断是否是管理员
                boolean isAdmin = "admin".equalsIgnoreCase(role);

                // 创建权限列表，根据角色动态赋予权限
                var authorities = List.of(new SimpleGrantedAuthority("ROLE_" + role.toUpperCase()));

                // 使用从 token 中提取的角色信息设置用户身份
                var auth = new UsernamePasswordAuthenticationToken(uid, null, authorities);  // 使用动态角色
                auth.setDetails(new WebAuthenticationDetailsSource().buildDetails(req));

                // 设置 SecurityContext
                SecurityContextHolder.getContext().setAuthentication(auth);

                // 如果是管理员，你可以在这里做一些额外的处理
                if (isAdmin) {
                    // 这里你可以添加管理员相关的逻辑，比如日志、额外的权限检查等
                    System.out.println("管理员身份验证通过");
                }
            } else {
                SecurityContextHolder.clearContext();  // token 无效时清除上下文
            }
        }

        // 放行请求
        chain.doFilter(req, res);
    }
}
